#include"Test.hpp"
#include<iostream>
#include<vector>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>

using namespace std;

#define N 2
const int ProcessCount=10;
vector<task_t> tasks;

//进程间通信之进程池(管道版)
//先描述
class Channel
{
public:
    //构造
    Channel(int cmdfd,pid_t slaverid,string processname)
    :_cmdfd(cmdfd)
    ,_slaverid(slaverid)
    ,_processname(processname)
    {
    }
    //析构，默认生成的就够用了
private:
    int _cmdfd;               // 发送任务的文件描述符
    pid_t _slaverid;          // 子进程的PID
    string _processname;      // 子进程的名字 -- 方便我们打印日志
};

void slaver()
{
    //read
    while(true)
    {
        int cmdcode=0;
        int n=read(0,&cmdcode,sizeof(int));
        if(n==sizeof(int))
        {
            //执行对应从键盘输入的任务列表号
            cout<<"slaver get a command["<<getpid()<<"]:"<<"任务号是："<<cmdcode<<endl;
            if(cmdcode>=0&&cmdcode<tasks.size())
            {
                tasks[cmdcode]();
            }
        }
        else
        break;
    }   
}
void InitProcessPool(vector<Channel>&channels)
{
    for(size_t i=0;i<=ProcessCount;i++)
    {
        int pipefd[N]={0};
        int n=pipe(pipefd);
        assert(!n);
        (void)n;

        pid_t id=fork();
        if(id==0)
        {
            //child
            close(pipefd[1]);
            dup2(pipefd[0],0);//从键盘读
            close(pipefd[0]);

            slaver();

            exit(0);
        }
        //父进程
        close(pipefd[0]);
        string name="process-"+to_string (i);
        channels.push_back(Channel(pipefd[1],id,name));

    }
}
void menu()
{
    
}
void ctrlSlaver(vector<Channel>&channels)
{
    menu();
}
int main()
{
    //加载任务
    LoadTask(&tasks);
    
    srand((unsigned)time(nullptr));//种下一颗随机数的种子
    //因为这里的进程池是由管道（多个）组成的，必然要管理和组织
    vector<Channel> channels;

    InitProcessPool(channels);
    //开始控制子进程
    ctrlSlaver(channels);
    return 0;
}
